#include "StdAfx.h"

#include <QtTreePropertyBrowser>
#include <qtpropertybrowser.h>
#include <QtVariantProperty>
#include <qteditorfactory.h>
#include <QElapsedTimer>

#include "vblank.h"
#include "vcontrol.h"
#include "vstyle.h"
#include "vdata.h"

#include "vblankview.h"
#include "../vcommon/vflowlayout.h"
#include "../Vidar3/vblankeditorview.h"

namespace
{
	const QString QML_SCRIPT_BEGIN = "import Qt 4.7; import VControls 1.0; VBlank {";
	const QString QML_SCRIPT_END = "}";

	const int marginLeft = 20;
	const int marginRight = 20;
	const int marginTop = 20;
	const int marginBottom = 20;

	const qreal A4Width = 8.268; // inches
	const qreal A4Height = 11.693;
}

int inchesToPixels(qreal inches, QPaintDevice *device)
{
	return qRound(inches * device->logicalDpiY());
}

//////////////////////////////////////////////////////////////////////////
// VBlankEditor
VBlankEditor::VBlankEditor(QWidget* parent)
:QTextEdit(parent)
, m_curBlockIdx(0)
{
	setReadOnly(true);
}

void VBlankEditor::canEditBlock(bool canEdit)
{
	setReadOnly(!canEdit);
}

void VBlankEditor::keyPressEvent(QKeyEvent *e)
{
	switch (e->key())
	{
	case Qt::Key_Tab:	
		{
			QTextBlock block(nextSelectedBlock());
			selectBlock(block);
			QTextCursor tc(textCursor());
			tc.setPosition(block.position());
			setTextCursor(tc);
		}
		return;

	case Qt::Key_Left:
		{
			if (textCursor().atBlockStart())
				return;
		}
		break;

	case Qt::Key_Right:
		{
			if (textCursor().atBlockEnd())
				return;
		}
		break;

	case Qt::Key_Up:
	case Qt::Key_Down:
		return;
	}

	QTextEdit::keyPressEvent(e);
}

void VBlankEditor::updateUserData()
{
	m_userData.clear();
	m_curBlockIdx = 0;

	QTextBlock bl = document()->begin();
	while(bl.isValid())
	{
		VControlBlockUserData* ud = static_cast<VControlBlockUserData*>(bl.userData());
		
		if (ud)
		{
			if (ud->control()->type() == VAbstractControl::Comment || ud->control()->type() == VAbstractControl::TextEdit )
			{
				/*int blockCount = ud->control()->value().toString().split("\n").count();
				// merge blocks bounding rects
				QRect r;
				for (int i = 0; i< blockCount; ++i)
				{
					if (bl.isValid())
					{
						QRect rr = document()->documentLayout()->blockBoundingRect(bl).toRect();
						r.setHeight(r.height()+rr.height());
					}
					
					bl = bl.next();
				}
				
				bl = bl.previous();
				qDebug() << r;
				ud->control()->setRect(r);*/
			}
			else
			{
				ud->control()->setRect(document()->documentLayout()->blockBoundingRect(bl).toRect());
			}

			m_userData << ud;

			//qDebug() << ud->control()->typeToString() << bl.text();
		}

		bl = bl.next();
	}

	selectBlock(nextSelectedBlock());
}

void VBlankEditor::selectBlock(const QTextBlock& block)
{
	QTextCursor tc(textCursor());

	tc.clearSelection();
	tc.setPosition(block.position(), QTextCursor::MoveAnchor);
	tc.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, block.length()-1);
	QTextCharFormat cf = block.charFormat();
	QBrush brBgColor(QColor(200, 200, 200));
	cf.setBackground(brBgColor);

	QList<QTextEdit::ExtraSelection> listSel;
	QTextEdit::ExtraSelection sel;
	sel.cursor = tc;
	sel.format = cf;
	listSel << sel;
	setExtraSelections(listSel);
}

QTextBlock VBlankEditor::nextSelectedBlock()
{
	QTextBlock bl = document()->begin();

	if (m_userData.isEmpty())
		return document()->begin();

	while(bl.isValid())
	{
		if (bl.userData() == m_userData[m_curBlockIdx])
		{			
			m_curBlockIdx++;

			if (m_curBlockIdx>=m_userData.count())
				m_curBlockIdx = 0;

			return bl;
		}

		bl = bl.next();
	}

	return document()->begin();
}

int VBlankEditor::updateCurentBlockIdx()
{
	//update curent block index
	QTextBlock block = document()->findBlock(textCursor().position());

	for (int i=0; i<m_userData.count(); ++i)
		if (block.userData() == m_userData[i])
		{			
			m_curBlockIdx = i+1;

			if (m_curBlockIdx>=m_userData.count())
				m_curBlockIdx = 0;

			return m_curBlockIdx;
		}

		return 0;
}

VBlankView::VBlankView(QWidget *parent)
	: QObject(parent)
{
	m_bkgWidget = new QWidget(parent);
	//QGridLayout* l = new QGridLayout(m_bkgWidget);
	//m_edit = new QTextEdit(m_bkgWidget);	
	//l->addWidget(m_edit);

	QGridLayout *gridLayout1;
	QScrollArea *scrollArea;
	QWidget *scrollAreaWidgetContents;
	QGridLayout *gridLayout;

	gridLayout1 = new QGridLayout(m_bkgWidget);	
	scrollArea = new QScrollArea(m_bkgWidget);
	scrollAreaWidgetContents = new QWidget();
	scrollArea->setWidget(scrollAreaWidgetContents);
	gridLayout1->addWidget(scrollArea, 0, 0, 1, 1);

	m_blankEditor = new VBlankEditor(scrollAreaWidgetContents);
	
	// A4 page size
	QSizeF page(inchesToPixels(A4Width, m_blankEditor), inchesToPixels(A4Height, m_blankEditor));

	m_blankEditor->setFrameShape(QFrame::NoFrame);
	m_blankEditor->document()->setPageSize(page);
	
	scrollAreaWidgetContents->setFixedSize(page.width()+5, page.height());
	gridLayout = new QGridLayout(scrollAreaWidgetContents);

	gridLayout->addWidget(m_blankEditor, 0, 0, 1, 1);

	connect(m_blankEditor, SIGNAL(currentCharFormatChanged(const QTextCharFormat&)),
		this, SLOT(currentCharFormatChange(const QTextCharFormat &)));

	connect(m_blankEditor, SIGNAL(cursorPositionChanged()), 
		this, SLOT(cursorPositionChange()));

	//gridLayout->setMargin(0);
	//gridLayout1->setMargin(0);

	//connect(this, SIGNAL(canEditedBlock(bool)), 
	//	m_blankEditor, SLOT(canEditBlock(bool)));
}

VBlankView::~VBlankView()
{

}

void VBlankView::cursorPositionChange()
{
	QTextCursor tc(m_blankEditor->textCursor());
	QTextTable* table = tc.currentTable();
	QTextBlock block = m_blankEditor->document()->findBlock(tc.position());
		
	//if (table)
	//	qDebug() << table->document() << m_blankEditor->document();//->blockCount();
	
	VControlBlockUserData* userData = static_cast<VControlBlockUserData*>(block.userData());
	if (table && userData)
	{
		if (userData->control()->type() != VAbstractControl::Comment)// && ud->control()->type() == VAbstractControl::TextEdit )
		{
			VAbstractControl* le = qobject_cast<VAbstractControl*>(userData->control());
			QRectF rf(m_blankEditor->document()->documentLayout()->blockBoundingRect(block));
			le->update(m_blankEditor, rf.toRect());
		}
		
		emit controlClicked(userData->control());

		/*if (userData->control()->type() == VAbstractControl::Comment)
		{
			emit canEditedBlock(false);			
		}
		else
		{
			//emit canEditedBlock(true);
			m_blankEditor->updateCurentBlockIdx();
			m_blankEditor->selectBlock(block);
		}*/
	}
}

void VBlankView::currentCharFormatChange(const QTextCharFormat& f)
{
}

//fi zero width
QVector<QTextLength> recalcTableWidth(const QVector<QTextLength>& tableWidth)
{
	return QVector<QTextLength>();
}

QList<VBlankView::TableConst> VBlankView::calcTablesConstrains(const VBlank* blank)
{
	QList<TableConst> widths;
	
	if (!blank)
		return widths;

	QSizeF pageSize(inchesToPixels(A4Width, m_blankEditor), 
		inchesToPixels(A4Height, m_blankEditor));

	TableConst colSumWidth;
	
	for (int i=0; i<blank->controlList().count(); ++i)
	{
		VLineBreak* br = qobject_cast<VLineBreak*>(blank->controlList().at(i));
		if(!br)
		{
			int width;// = blank->controlList().at(i)->width();
			/*if (width <= 0)
				colSumWidth << QTextLength(QTextLength::VariableLength, width);
			else*/
				//colSumWidth << QTextLength(QTextLength::PercentageLength, width);
		}
		else
		{
			widths << colSumWidth;
			colSumWidth.clear();
		}
	}
	
	if (blank->controlList().at(blank->controlList().count()-1)->type() != VAbstractControl::LineBreak)
		widths << colSumWidth;

	/*for (int i=0; i<widths.count(); ++i)
		for (int k=0; k<widths[i].count(); k++)
			qDebug() << widths[i][k].value(0);
*/
	
	/*for (int i=0; i<listCol.count(); ++i)
	{
		int total = 0;
		int zeroCells = 0;
		for (int k=0; k<listCol[i].count(); ++k)
		{
			if (listCol[i][k])
				total+=listCol[i][k];
			else
				++zeroCells;
		}

		if (zeroCells)
		{
			int cellWidth = (pageSize.width()-total-32)/zeroCells;

			for (int k=0; k<listCol[i].count(); ++k)
			{
				if (listCol[i][k] == 0)
					listCol[i][k] = cellWidth;
			}
		}
	}*/

	/*for (int i=0; i<listCol.count(); ++i)
	{
		int total = 0;		
		for (int k=0; k<listCol[i].count(); ++k)
			total+=listCol[i][k];

		int total1 = 0;		
		for (int k=0; k<listCol[i].count()-1; ++k)
			total1+=listCol[i][k];
		
		int lastCellWidth = pageSize.width()-32 - total1;		
		listCol[i][listCol[i].count()-1] = lastCellWidth;
	}*/
	return widths;
}

void VBlankView::update(const VBlank* blank)
{
	if (!blank)
		return;

	if (blank->isEmpty())
		return;

	m_blankEditor->clear();
	m_stackControls.clear();

	QList<TableConst> widths(calcTablesConstrains(blank));
	
	QTextCursor cursor(m_blankEditor->textCursor());

	QTextTableFormat tableFormat;
	tableFormat.setBorderStyle(QTextFrameFormat::BorderStyle_None);
	QTextTable *table = 0;
	QTextTableCellFormat cellFormat;	

	int curHorPos = 0;	
	cursor.beginEditBlock();

	int counter = 0;
	for (int i=0; i<blank->controlList().count(); ++i)
	{
		if (!table)
		{
			table = m_blankEditor->textCursor().insertTable(1, 1, tableFormat);
		}
		else
		{
			if (!table->cellAt(0/*table->rows()-1*/, curHorPos).isValid())
				table->appendColumns(1);			
		}
		
		QTextCursor cellCursor = table->cellAt(0/*table->rows()-1*/, curHorPos).firstCursorPosition();

		if (VLineBreak* br = qobject_cast<VLineBreak*>(blank->controlList().at(i)))
		{
			//table->appendRows(1);			
			table->removeColumns(table->columns()-1, 1);

			QTextBlock bl = table->document()->begin();
			while(bl.isValid())
			{
				if (!bl.text().isEmpty() && !bl.userData() && counter < m_stackControls.count())
					bl.setUserData(new VControlBlockUserData(m_stackControls.at(counter++)));

				bl = bl.next();
			}

			/*QVector<QTextLength> constraints;

			// merge cells			
			//for (int rows=0; rows<table->rows(); ++rows)
			QList<int> widths = listCol[curVerPos++];
			{
				/*int delta = 0;
				for (int col=table->columns()-1; col>=0; --col)
				{
					QTextCursor cell = table->cellAt(rows, col).firstCursorPosition();
					if (cell.block().text().isEmpty())
						delta++;
				}				
			

				qDebug() << "before" << table->columns() << table->rows();
				table->mergeCells(rows, table->columns()-delta-1, 1, delta+1);
				qDebug() << "after" << table->columns() << table->rows();* /

				for (int i=0; i<table->columns(); i++)
				{					
					//qreal cellWidth = 100.0/(table->columns() - delta);
					qreal cellWidth = (pageSize.width()-32)/table->columns();
					//constraints << QTextLength(QTextLength::PercentageLength, cellWidth);
					constraints << QTextLength(QTextLength::FixedLength, widths[i]);//cellWidth);
					//qDebug() << cellWidth;
				}
			}*/

			//set constrains
			
			QTextTableFormat tblFormat = table->format();
			tblFormat.setColumnWidthConstraints(widths.takeFirst());
			table->setFormat(tblFormat);

			table = m_blankEditor->textCursor().insertTable(1, 1, tableFormat);//cursor.insertTable(1, 1, tableFormat);
			curHorPos = 0;
			//++curVerPos;
		}
		else
		{
			Qt::Alignment align = 0;

			switch (blank->controlList().at(i)->align())
			{
			case VAbstractControl::AlignLeft:
				align = Qt::AlignLeft;
				break;
			case VAbstractControl::AlignCenter:
				align = Qt::AlignHCenter;
				break;
			case VAbstractControl::AlignRight:
				align = Qt::AlignRight;
				break;
			}

			QTextBlockFormat blockAlignment;
			blockAlignment.setAlignment(align);
			cellCursor.setBlockFormat(blockAlignment);
						
			/*if (VTable* t = qobject_cast<VTable*>(blank->controlList().at(i)))
			{
				QTextTable* vTable = cellCursor.insertTable(t->cells().count(&t->cells())/t->header().count(&t->header()), t->header().count(&t->header()));

				for (int ii=0; ii<t->cells().count(&t->cells()); ++ii)
				{										
					int colIndex = ii%t->header().count(&t->header());
					QTextTableCell vCell = vTable->cellAt((ii-colIndex)/t->header().count(&t->header()), colIndex);

					if (!vCell.isValid())
						continue;

					QTextCursor vCursor = vCell.firstCursorPosition();

					VCell* c = t->cells().at(&t->cells(), ii);
					vCursor.insertText(c->value().toString());

					/*VAbstractData* data = t->header().at(&t->header(), ii%t->header().count(&t->header()));				
					if (VString* var = qobject_cast<VString*>(data))
						qDebug() << c->value().toString();
					else if (VInteger* var = qobject_cast<VInteger*>(data))
						qDebug() << c->value().toInt();
					else if (VReal* var = qobject_cast<VReal*>(data))
						qDebug() << c->value().toReal();
					else if (VDate* var = qobject_cast<VDate*>(data))
						qDebug() << c->value().toDate().toString("dd/MM/yy");
					else if (VTime* var = qobject_cast<VTime*>(data))
						qDebug() << c->value().toTime().toString();* /
				}				
			}
			else*/ if (VImage* image = qobject_cast<VImage*>(blank->controlList().at(i)))
			{
				//cellCursor.insertImage(image->image());
			}
			else /*if (blank->controlCollection().at(i)->type() == VAbstractControl::TextEdit ||
				blank->controlCollection().at(i)->type() == VAbstractControl::Comment ||
				blank->controlCollection().at(i)->type() == VAbstractControl::LineEdit||
				blank->controlCollection().at(i)->type() == VAbstractControl::IntEdit)*/
			{
				VAbstractControl* edit = blank->controlList().at(i);

				if (!edit)
					continue;

				QTextCharFormat charFormat;
				charFormat.setFont(edit->style()->font());
				QBrush brTextColor(edit->style()->color());
				QBrush brBgColor(edit->style()->bgColor());
				charFormat.setForeground(brTextColor);
				charFormat.setBackground(brBgColor);
				charFormat.setVerticalAlignment(QTextCharFormat::AlignBottom);
				table->cellAt(0, curHorPos).setFormat(charFormat);
				
				/*if (blank->controlList().at(i)->type() == VAbstractControl::DateEdit)
				{
					VDateEdit* de = qobject_cast<VDateEdit*>(blank->controlList().at(i));					
					QString sd1(QDate::fromString(de->value().toString(), de->format()).toString(de->format()));
					QString sd2(de->value().toDate().toString(de->format()));
					if (sd1.isEmpty())
						cellCursor.insertText(sd2);
					else
						cellCursor.insertText(sd1);
				}
				else if (blank->controlList().at(i)->type() == VAbstractControl::TimeEdit)
				{
					VTimeEdit* te = qobject_cast<VTimeEdit*>(blank->controlList().at(i));
					QTime t(QTime::fromString(te->value().toString(), te->format()));
					cellCursor.insertText(t.toString(te->format()));
				}
				else*/
				{
					cellCursor.insertText(edit->value().toString());
				}
			}

			++curHorPos;
		}

		if (blank->controlList().at(i)->type() != VAbstractControl::LineBreak)
			m_stackControls << blank->controlList().at(i);
	}

	if (blank->controlList().at(blank->controlList().count()-1)->type() != VAbstractControl::LineBreak)	
	{
		/*QVector<QTextLength> constraints;

			// merge cells			
			//for (int rows=0; rows<table->rows(); ++rows)
			QList<int> widths = listCol[listCol.count()-1];
			{
				/*int delta = 0;
				for (int col=table->columns()-1; col>=0; --col)
				{
					QTextCursor cell = table->cellAt(rows, col).firstCursorPosition();
					if (cell.block().text().isEmpty())
						delta++;
				}				
			

				qDebug() << "before" << table->columns() << table->rows();
				table->mergeCells(rows, table->columns()-delta-1, 1, delta+1);
				qDebug() << "after" << table->columns() << table->rows();* /

				for (int i=0; i<table->columns(); i++)
				{					
					//qreal cellWidth = 100.0/(table->columns() - delta);
					qreal cellWidth = (pageSize.width()-32)/table->columns();
					//constraints << QTextLength(QTextLength::PercentageLength, cellWidth);
					constraints << QTextLength(QTextLength::FixedLength, widths[i]);//cellWidth);
					//qDebug() << cellWidth;
				}
			}*/

			//set constrains
			
			QTextTableFormat tblFormat = table->format();
			tblFormat.setColumnWidthConstraints(widths.takeFirst());
			table->setFormat(tblFormat);
	}

	cursor.endEditBlock();
	m_blankEditor->updateUserData();
}

//////////////////////////////////////////////////////////////////////////
// VPropertyBrowserHelper
VPropertyBrowserHelper::VPropertyBrowserHelper(QObject* parent)
	:QObject(parent)
{

	QTabWidget* tw = qobject_cast<QTabWidget*>(parent);
	Q_ASSERT(tw);
	m_propEditor = new QtTreePropertyBrowser(tw);
	tw->addTab(m_propEditor, tr("Property"));
	
	m_variantManager = new QtVariantPropertyManager(this);
	QtVariantEditorFactory *m_variantFactory = new QtVariantEditorFactory(this);

	QtBoolPropertyManager *boolManager = new QtBoolPropertyManager(this);
	QtIntPropertyManager *intManager = new QtIntPropertyManager(this);
	QtStringPropertyManager *stringManager = new QtStringPropertyManager(this);
	QtSizePropertyManager *sizeManager = new QtSizePropertyManager(this);
	QtRectPropertyManager *rectManager = new QtRectPropertyManager(this);
	QtSizePolicyPropertyManager *sizePolicyManager = new QtSizePolicyPropertyManager(this);
	QtEnumPropertyManager *enumManager = new QtEnumPropertyManager(this);
	QtGroupPropertyManager *groupManager = new QtGroupPropertyManager(this);
	
	QtCheckBoxFactory *checkBoxFactory = new QtCheckBoxFactory(this);
	QtSpinBoxFactory *spinBoxFactory = new QtSpinBoxFactory(this);
	QtSliderFactory *sliderFactory = new QtSliderFactory(this);
	QtScrollBarFactory *scrollBarFactory = new QtScrollBarFactory(this);
	QtLineEditFactory *lineEditFactory = new QtLineEditFactory(this);
	QtEnumEditorFactory *comboBoxFactory = new QtEnumEditorFactory(this);

	m_propEditor->setFactoryForManager(boolManager, checkBoxFactory);
	m_propEditor->setFactoryForManager(intManager, spinBoxFactory);
	m_propEditor->setFactoryForManager(stringManager, lineEditFactory);
	m_propEditor->setFactoryForManager(sizeManager->subIntPropertyManager(), spinBoxFactory);
	m_propEditor->setFactoryForManager(rectManager->subIntPropertyManager(), spinBoxFactory);
	m_propEditor->setFactoryForManager(sizePolicyManager->subIntPropertyManager(), spinBoxFactory);
	m_propEditor->setFactoryForManager(sizePolicyManager->subEnumPropertyManager(), comboBoxFactory);
	m_propEditor->setFactoryForManager(enumManager, comboBoxFactory);

	m_propEditor->setFactoryForManager(m_variantManager, m_variantFactory);
	connect(m_variantManager, SIGNAL(valueChanged(QtProperty *, const QVariant &)),
		this, SLOT(valueChanged(QtProperty *, const QVariant &)));
}

VPropertyBrowserHelper::~VPropertyBrowserHelper()
{

}

void VPropertyBrowserHelper::updateExpandState()
{
	QList<QtBrowserItem *> list = m_propEditor->topLevelItems();
	QListIterator<QtBrowserItem *> it(list);
	while (it.hasNext())
	{
		QtBrowserItem *item = it.next();
		QtProperty *prop = item->property();
		idToExpanded[propertyToId[prop]] = m_propEditor->isExpanded(item);
	}
}

void VPropertyBrowserHelper::addProperty(QtVariantProperty *property, const QString &id)
{
	propertyToId[property] = id;
	idToProperty[id] = property;
	QtBrowserItem *item = m_propEditor->addProperty(property);
	if (idToExpanded.contains(id))
		m_propEditor->setExpanded(item, idToExpanded[id]);
}

void VPropertyBrowserHelper::valueChanged(QtProperty *property, const QVariant &value)
{
	if (!propertyToId.contains(property))
		return;

	QString id = propertyToId[property];
	m_curControl->setValue(value);
	m_curControl->update();
}

void VPropertyBrowserHelper::controlClick(VAbstractControl* control)
{
	updateExpandState();

	QMap<QtProperty *, QString>::ConstIterator itProp = propertyToId.constBegin();
	while (itProp != propertyToId.constEnd())
	{
		delete itProp.key();
		itProp++;
	}
	propertyToId.clear();
	idToProperty.clear();

	m_curControl = control;
	QtVariantProperty *property;	
	const QMetaObject* obj = m_curControl->metaObject();
	for (int i=0; i<obj->propertyCount(); ++i)
	{
		QString propName(obj->property(i).name());
		if (propName == "objectName")
			continue;

		property = m_variantManager->addProperty(m_curControl->property(obj->property(i).name()).type(), propName);
		QVariant value(m_curControl->property(obj->property(i).name()));
		if (property)
		{
			property->setValue(value);
			addProperty(property, QLatin1String(obj->property(i).name()));
		}
	}
}

//////////////////////////////////////////////////////////////////////////
// VObjectInspector
VObjectInspector::VObjectInspector(QWidget* parent)
: QObject(parent)
{
	m_objInspDoc = new QDockWidget(tr("Object Inspector"), parent);
	m_objInspDoc->setAllowedAreas(Qt::NoDockWidgetArea);
	m_objInspDoc->setFeatures(QDockWidget::NoDockWidgetFeatures);	

	m_objInspTab = new QTabWidget(m_objInspDoc);	
	m_objInspDoc->setWidget(m_objInspTab);

	m_propHelper = new VPropertyBrowserHelper(m_objInspTab);
}

VObjectInspector::~VObjectInspector()
{
	if (m_objInspDoc)
		delete m_objInspDoc;
}

//////////////////////////////////////////////////////////////////////////
// VBlankWidgetView
VBlankWidgetView::VBlankWidgetView(bool hasObjectInspector, QWidget *parent)
	: QObject(parent)
	, m_firstChild(0)
	, m_scrollArea(0)
	, m_scrollAreaWidgetContents(0)
	, m_mainLayout(0)
	, m_hasObjectInspector(hasObjectInspector)
{
	m_keyPressEater = new KeyPressEater;
	//m_bkgWidget = new QWidget(parent);
	
	//QGridLayout *gridLayout1;			
	//gridLayout1 = new QGridLayout(parent);
	//gridLayout1->setAlignment(Qt::AlignHCenter);
	m_scrollArea = new VScrollAreaHelper;
	m_scrollArea->setObjectName("m_scrollArea");
	m_scrollArea->setWidgetResizable(true);
	m_scrollArea->setFocusPolicy(Qt::NoFocus);
	//m_scrollArea->installEventFilter(m_keyPressEater);
	//QTabWidget* tabWidget = qobject_cast<QTabWidget*>(parent);
	//tabWidget->addTab(m_scrollArea, "0000");

	
	
	if (m_hasObjectInspector)
	{
		m_objInspector = new VObjectInspector;//(m_scrollArea);	
		m_objInspector->widget()->show();
		//QSplitter* splitter = new QSplitter;//(m_scrollArea);
		//splitter->addWidget(m_scrollArea);
		//splitter->addWidget(m_objInspector->widget());
		//gridLayout1->addWidget(splitter);
	}
	//else
		//gridLayout1->addWidget(m_scrollArea);
	//	m_scrollArea->setLayout(gridLayout1);

	//connect(QApplication::instance(), SIGNAL(focusChanged(QWidget*, QWidget*)), this, SLOT(focusChange(QWidget*, QWidget*)));
}

VBlankWidgetView::~VBlankWidgetView()
{
	//disconnect(QApplication::instance(), SIGNAL(focusChanged(QWidget*, QWidget*)), this, SLOT(focusChange(QWidget*, QWidget*)));
}

void VBlankWidgetView::update(const VBlank* blank)
{
	QElapsedTimer timer;
	timer.start();

	if (!blank)
		return;

	if (blank->isEmpty())
		return;

	qDebug() << "update";

	/*m_focusWidgets.clear();
	foreach(VAbstractControl* c, blank->controlWithFocusList())
		m_focusWidgets[c->widget()] = c;

	m_absControls.clear();
	m_absControls = blank->controlWithFocusList();*/

	if (m_mainLayout)
	{
		delete m_mainLayout;
		delete m_scrollAreaWidgetContents;
		m_firstChild = 0;
	}

	// A4 page size
	QSizeF page(inchesToPixels(A4Width, m_scrollArea), inchesToPixels(A4Height, m_scrollArea));

	m_scrollAreaWidgetContents = new QWidget;//(m_scrollArea);
	m_scrollAreaWidgetContents->setObjectName("m_scrollAreaWidgetContents");
	m_scrollArea->setWidget(m_scrollAreaWidgetContents);
	m_scrollAreaWidgetContents->setFixedWidth(page.width()-100);
	m_scrollArea->setFocusProxy(m_scrollAreaWidgetContents);
	//m_scrollAreaWidgetContents->installEventFilter(m_keyPressEater);
	//if (!m_absControls.isEmpty())
	//m_keyPressEater->setFirstLastFocusWidget(m_absControls[0]->widget(), m_absControls[m_absControls.count()-1]->widget());
	//m_scrollAreaWidgetContents->setTabOrder(m_absControls[0]->widget(), m_absControls[1]->widget());
	
	QString ss(QString("background-color: rgb(%1, %2, %3);").arg(blank->backgroundColor().red()).arg(blank->backgroundColor().green()).arg(blank->backgroundColor().blue()));
	m_scrollAreaWidgetContents->setStyleSheet(ss);
	//m_scrollAreaWidgetContents->setStyleSheet("background-color: rgb(250, 250, 250);"); // border: none
	
	/*#define paperDelta 10
	QRect r(m_scrollAreaWidgetContents->geometry());
	r.moveTo(paperDelta, paperDelta);
	m_scrollAreaWidgetContents->setGeometry(r);
	qDebug() << m_scrollAreaWidgetContents->geometry();*/
	
	m_mainLayout = new VPageLayout;//(m_scrollAreaWidgetContents);
	m_mainLayout->setPageWidth(page.width()-100);
	m_scrollAreaWidgetContents->setLayout(m_mainLayout);
	
	for (int i=0; i<blank->controlList().count(); ++i)
	{
		VAbstractControl* c = blank->controlList().at(i);
		
		switch(c->type())
		{
			case VAbstractControl::Line:
			{
				m_mainLayout->addWidget(c->widget());
				break;
			}

			/*case VAbstractControl::LineBreak:
			{
				if (l->count() == 1 && (i-1)>=0)
				{
					QGridLayout* gl = new QGridLayout;
					gl->setSpacing(0);	
					gl->setContentsMargins(0, 0, 0, 0);
					gl->addWidget(l->itemAt(0)->widget(), 0, 0, blank->controlList().at(i-1)->alignToQT());
					m_mainLayout->addLayout(gl);
				}
				else
				{
					m_mainLayout->addLayout(l);					
				}

				l = new VFlowLayout;
				break;
			}*/

			case VAbstractControl::FLayout:
				{
					VFLayout* cfl = qobject_cast<VFLayout*>(c);
					VFlowLayout* fl = new VFlowLayout;
					m_mainLayout->addLayout(fl);

					for (int k=0; k<cfl->controlList().count(); ++k)
					{
						if (cfl->controlList().at(k)->widget())
						{
							if(cfl->controlList().at(k)->type() == VAbstractControl::TextEdit)
							{
								fl->addWidget(cfl->controlList().at(k)->widget());
								//cfl->controlList().at(k)->update();
							}
							else
							{
								fl->addWidget(cfl->controlList().at(k)->widget());
								cfl->controlList().at(k)->setAutoResize(true);
							}
						}
					}

					/*if (fl->count()>0)
						m_mainLayout->addLayout(fl);
					else
						delete fl;*/
					break;
				}

			case VAbstractControl::HLayout:
			{
				VHLayout* chl = qobject_cast<VHLayout*>(c);
				QHBoxLayout* hl = new QHBoxLayout;
				
				for (int k=0; k<chl->controlList().count(); ++k)
				{
					if (chl->controlList().at(k)->type() == VAbstractControl::TextEdit)
					{
						VTextEdit* te = qobject_cast<VTextEdit*>(chl->controlList().at(k));
						te->setInFlowLayout(false);
					}

					hl->addWidget(chl->controlList().at(k)->widget());
				}

				m_mainLayout->addLayout(hl);
				break;
			}

			case VAbstractControl::TableLayout:
				{
					VTableLayout* tl = qobject_cast<VTableLayout*>(c);
					QGridLayout* gl = new QGridLayout;
					gl->setSpacing(0);
					gl->setContentsMargins(0, 0, 0, 0);

					for (int k = 0; k < tl->rowList().count(); ++k)
						for (int m = 0; m < tl->rowList().at(k)->controlList().count(); ++m)
						{
							if (tl->rowList().at(k)->controlList().at(m)->type() == VAbstractControl::TextEdit)
							{
								VTextEdit* te = qobject_cast<VTextEdit*>(tl->rowList().at(k)->controlList().at(m));
								if (te)
									te->setInFlowLayout(false);
							}

							//tl->rowList().at(k)->controlList().at(m)->setAutoResize(true);
							gl->addWidget(tl->rowList().at(k)->controlList().at(m)->widget(), k, m);
						}

					m_mainLayout->addLayout(gl);
					break;
				}
			
			/*default:
			{
				if (QWidget* w = blank->controlList().at(i)->widget())
				{
					l->addWidget(blank->controlList().at(i)->widget());
					//blank->controlList().at(i)->setAutoResize(true);
					//m_mainLayout->addLayout(l);
				}
			}*/
		}
	}

	for (int i=0; i<blank->controlList().count(); ++i)
	{
		blank->controlList().at(i)->update();

		/*QWidget* w(blank->controlList().at(i)->widget());
		if (w)
			w->setParent(m_scrollAreaWidgetContents);*/
	}

	//if (!m_absControls.isEmpty())
	//	(*m_absControls.begin())->widget()->setFocus();

	//qDebug() << timer.elapsed();
}

void VBlankWidgetView::focusChange(QWidget* old, QWidget* now)
{
	//qDebug() << old << now << QApplication::focusWidget();
	return;

// 	if (qobject_cast<QTextEdit*>(now))
// 		qDebug() << qobject_cast<QTextEdit*>(now)->toPlainText();
	/*if (qobject_cast<VBlankEditorTreeWidget*>(now) && m_firstChild)
	{
		m_firstChild->setFocus();
	}*/
	//QWidget* w = m_widgets.end().key(); 
	//qDebug() << m_focusWidgets;
	/*QMap<QWidget*, VAbstractControl*>::const_iterator it = m_focusWidgets.find(now);
	m_objInspector->propertyBrowser()->controlClick(it.value());*/

	if (m_absControls.count() <= 1 || m_focusWidgets.isEmpty() || !now)
		return;
	
	/*QMap<QWidget*, VAbstractControl*>::const_iterator it = m_focusWidgets.find(now);
	if (it != m_focusWidgets.end())
		m_curControl = it.value();*/
	
	//else
	//	m_curControl = 0;

//	m_curControl->widget()->setFocus();
	//if (it == m_focusWidgets.end())
	//{
		//return;

	if (m_hasObjectInspector)
		foreach(VAbstractControl*c, m_absControls)
		{
			if (c && c->widget() == now)
			{
				m_objInspector->propertyBrowser()->controlClick(c);
				break;
			}
		}

	//VAbstractControl* c(*(--m_absControls.end()));
	//if (c && old == c->widget() && old->isVisible())
		//(*m_absControls.begin())->widget()->setFocus();
	//}

	VAbstractControl* c = m_absControls[m_absControls.count()-1];
	if (c && old == c->widget() && !qobject_cast<QComboBox*>(now) && old->isVisible())
		(*m_absControls.begin())->widget()->setFocus();

	/*QList<VAbstractControl*>::iterator it1 = m_absControls.end();
	--it1;
	if (old == (*it1)->widget() && !qobject_cast<QComboBox*>(now) && old->isVisible())
		(*m_absControls.begin())->widget()->setFocus();*/
	
		/*if (it1 != m_absControls.begin() && old == (*it1)->widget() && old->isVisible())
	{
		(*m_absControls.begin())->widget()->setFocus();
	}*/
}